package com.tobby.demo.java8.lamda;

import java.lang.annotation.Retention;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Hello world!
 *
 */
public class LamdaTest {

	int temp1 = 1;
	static int temp2 = 2;

	public static void main(String[] args) throws Exception {
		LamdaTest test = new LamdaTest();
		test.nestedLamda();
		test.generatorFunction();
	}

	// 给出一个String类型的数组，找出其中各个素数，并统计其出现次数
	private void primaryOccurance(String... numbers) {
		List<String> list = Arrays.asList(numbers);
		Map<Integer, Integer> map = list.stream().map(e -> new Integer(e))
				.filter(e -> Prime.isPrime(e))
				.collect(Collectors.groupingBy(p -> p, Collectors.summingInt(p -> 1)));
	}

	// 给出一个String类型的数组，求其中所有不重复素数的和
	private void distinctPrimarySum(String... numbers) {
		List<String> list = Arrays.asList(numbers);
		int sum = list.stream().map(e -> new Integer(e)).filter(e -> Prime.isPrime(e))
				.distinct().reduce(0, (x, y) -> x + y);
	}

	private void distinctPrimarySumWithMethodReferrence(String... numbers) {
		List<String> list = Arrays.asList(numbers);
		int sum = list.stream().map(Integer::new).filter(Prime::isPrime).mapToInt(null)
				.distinct().sum();
		System.out.println("Distinct prime sum is : " + sum);
	}

	private void boysAndGirls(List<Person> persons) {
		Map<Sex, Integer> result = persons
				.parallelStream()
				.filter(p -> p.getAge() >= 25 && p.getAge() <= 35)
				.collect(
						Collectors.groupingBy(p -> p.getSex(),
								Collectors.summingInt(p -> 1)));
		System.out.println("Boys and Girls Result " + result);
		System.out.println("Ratio (Male : Female) is : " + (float) result.get(Sex.MALE)
				/ result.get(Sex.FEMAL));
	}

	private void nestedLamda() throws Exception {
		Callable<Runnable> callable = () -> () -> {
			System.out.println("Nested lamda");
		};
		callable.call().run();
		Runnable runnable = () -> {
			System.out.println("Lamda Expression");
		};
		runnable.run();
		boolean flag = false;
		Callable<Integer> integerCallable = flag ? (() -> 42) : (() -> 24);
		System.out.println(integerCallable.call());
	}

	private void testCapture() {
		int temp3 = 3;
		final int temp4 = 4;
		int temp5 = 5;
		Function<Integer, Integer> f1 = i -> i + temp1;
		Function<Integer, Integer> f2 = i -> i + temp2;
		Function<Integer, Integer> f3 = i -> i + temp3;
		Function<Integer, Integer> f4 = i -> i + temp4;
		Function<Integer, Integer> f5 = i -> {
			// temp5 += i;
			return temp5;
		};
		// temp5 = 9;
	}

	private void generatorFunction() {
		Stream.generate(Math::random).limit(5).forEach(System.out::println);
	}

}
